package com.ruoyi.course.controller;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.course.constants.CourseScheduleConstants;
import com.ruoyi.course.domain.CourseSchedule;
import com.ruoyi.course.dto.BatchAddScheduleDto;
import com.ruoyi.course.dto.OneClickAddScheduleDto;
import com.ruoyi.course.service.ICourseScheduleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 课程安排Controller
 * 
 * @author ruoyi
 * @date 2025-01-01
 */
@RestController
@RequestMapping("/course/schedule")
public class CourseScheduleController extends BaseController
{
    @Autowired
    private ICourseScheduleService courseScheduleService;

    /**
     * 查询课程安排列表
     */
    @PreAuthorize("@ss.hasPermi('course:schedule:list')")
    @GetMapping("/list")
    public TableDataInfo list(CourseSchedule courseSchedule)
    {
        startPage();
        List<CourseSchedule> list = courseScheduleService.selectCourseScheduleList(courseSchedule);
        return getDataTable(list);
    }

    /**
     * 根据班级ID查询课程安排列表
     */
    @PreAuthorize("@ss.hasPermi('course:schedule:list')")
    @GetMapping("/list/{claId}")
    public AjaxResult getSchedulesByClaId(@PathVariable("claId") Long claId)
    {
        List<CourseSchedule> list = courseScheduleService.selectCourseScheduleByClaId(claId);
        return success(list);
    }

    /**
     * 获取课程安排详细信息
     */
    @PreAuthorize("@ss.hasPermi('course:schedule:query')")
    @GetMapping(value = "/{scheduleId}")
    public AjaxResult getInfo(@PathVariable("scheduleId") Long scheduleId)
    {
        return success(courseScheduleService.selectCourseScheduleByScheduleId(scheduleId));
    }

    /**
     * 新增单个课程安排
     */
    @PreAuthorize("@ss.hasPermi('course:schedule:add')")
    @Log(title = "课程安排", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody CourseSchedule courseSchedule)
    {
        // 检查时间冲突
        if (hasTimeConflict(courseSchedule)) {
            return error("该时间段已有课程安排，请选择其他时间");
        }
        
        // 设置默认状态
        if (courseSchedule.getStatus() == null) {
            courseSchedule.setStatus(CourseScheduleConstants.Status.ACTIVE);
        }
        
        return toAjax(courseScheduleService.insertCourseSchedule(courseSchedule));
    }

    /**
     * 一键添加课程（基于日期范围）
     */
    @PreAuthorize("@ss.hasPermi('course:schedule:add')")
    @Log(title = "一键添加课程", businessType = BusinessType.INSERT)
    @PostMapping("/batch")
    public AjaxResult batchAdd(@RequestBody BatchAddScheduleDto batchDto)
    {
        int result = courseScheduleService.batchInsertCourseSchedule(batchDto);
        return result > 0 ? success("成功添加 " + result + " 节课程") : error("添加失败");
    }

    /**
     * 一键加课（基于已有课程模式）
     */
    @PreAuthorize("@ss.hasPermi('course:schedule:add')")
    @Log(title = "一键加课", businessType = BusinessType.INSERT)
    @PostMapping("/oneClick")
    public AjaxResult oneClickAdd(@RequestBody OneClickAddScheduleDto oneClickDto)
    {
        try {
            int result = courseScheduleService.oneClickAddSchedule(oneClickDto);
            return result > 0 ? success("成功添加 " + result + " 节课程") : success("没有需要添加的课程");
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * 修改课程安排
     */
    @PreAuthorize("@ss.hasPermi('course:schedule:edit')")
    @Log(title = "课程安排", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody CourseSchedule courseSchedule)
    {
        // 检查时间冲突（排除自己）
        if (hasTimeConflictExcludeSelf(courseSchedule)) {
            return error("该时间段已有课程安排，请选择其他时间");
        }
        
        return toAjax(courseScheduleService.updateCourseSchedule(courseSchedule));
    }

    /**
     * 拖拽更新课程日期
     */
    @PreAuthorize("@ss.hasPermi('course:schedule:edit')")
    @Log(title = "拖拽更新课程日期", businessType = BusinessType.UPDATE)
    @PutMapping("/drag")
    public AjaxResult dragUpdateDate(@RequestBody CourseSchedule courseSchedule)
    {
        try {
            // 检查是否拖拽到过去的日期
            if (courseSchedule.getSpecificDate() != null) {
                java.time.LocalDate targetDate = java.time.LocalDate.parse(courseSchedule.getSpecificDate());
                java.time.LocalDate today = java.time.LocalDate.now();
                
                if (targetDate.isBefore(today) || targetDate.isEqual(today)) {
                    return error("不能将课程拖拽到今天或过去的日期");
                }
            }
            
            // 检查新日期时间冲突（排除自己）
            if (hasTimeConflictExcludeSelf(courseSchedule)) {
                return error("目标日期该时间段已有课程安排，请选择其他日期");
            }
            
            // 更新课程日期
            int result = courseScheduleService.updateCourseSchedule(courseSchedule);
            
            if (result > 0) {
                return success("课程日期更新成功");
            } else {
                return error("课程日期更新失败");
            }
            
        } catch (Exception e) {
            return error("操作失败：" + e.getMessage());
        }
    }

    /**
     * 删除课程安排（软删除）
     */
    @PreAuthorize("@ss.hasPermi('course:schedule:remove')")
    @Log(title = "课程安排", businessType = BusinessType.DELETE)
	@DeleteMapping("/{scheduleIds}")
    public AjaxResult remove(@PathVariable Long[] scheduleIds)
    {
        int result = 0;
        for (Long scheduleId : scheduleIds) {
            result += courseScheduleService.softDeleteCourseSchedule(scheduleId);
        }
        return result > 0 ? success("成功删除 " + result + " 节课程") : error("删除失败");
    }

    /**
     * 恢复课程安排
     */
    @PreAuthorize("@ss.hasPermi('course:schedule:edit')")
    @Log(title = "恢复课程安排", businessType = BusinessType.UPDATE)
    @PutMapping("/restore/{scheduleId}")
    public AjaxResult restore(@PathVariable Long scheduleId)
    {
        CourseSchedule courseSchedule = new CourseSchedule();
        courseSchedule.setScheduleId(scheduleId);
        courseSchedule.setStatus(CourseScheduleConstants.Status.ACTIVE);
        
        return toAjax(courseScheduleService.updateCourseSchedule(courseSchedule));
    }

    /**
     * 检查时间冲突
     */
    private boolean hasTimeConflict(CourseSchedule courseSchedule) {
        List<CourseSchedule> conflicts;
        
        // 检查具体日期冲突
        conflicts = courseScheduleService.checkTimeConflict(
            courseSchedule.getClaId(), 
            courseSchedule.getSpecificDate(), 
            courseSchedule.getTimePeriod()
        );
        
        return !conflicts.isEmpty();
    }

    /**
     * 检查时间冲突（排除自己）
     */
    private boolean hasTimeConflictExcludeSelf(CourseSchedule courseSchedule) {
        List<CourseSchedule> conflicts;
        
        conflicts = courseScheduleService.checkTimeConflict(
            courseSchedule.getClaId(), 
            courseSchedule.getSpecificDate(), 
            courseSchedule.getTimePeriod()
        );
        
        // 排除自己
        return conflicts.stream()
                .anyMatch(conflict -> !conflict.getScheduleId().equals(courseSchedule.getScheduleId()));
    }
}
